Adding OrderingSchema for ordering QuerySets #1291
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
The
FilterSchema
definition is a simple but effective approach to centralize logic around filtering QuerySets. A similar approach could be followed for ordering.Current for ordering and filtering in the same handler we would the following:
But what if we want to limit the API to allow ordering by just some of the fields. Or if we want to customize ordering based on custom fields and logic. What if we want to have a similar approach for other data sources, for example ElasticSearch.
Proposal
This PR propose to include a helper schema class, similar to FilteringSchema, but for ordering. It';s a simple schema class, with only one field:
order_by
, that accepts a list of string.The allowed fields can be specified through the Config inner class, and a Pydantic validator will check that the provided query values are part of the allowed fields.
The schema then will provide a
.sort()
method (similar to.filter()
) that we can use to pass the query set, and expect it ordered as a returned value.The values can be provided using django standard behavior for descending order.
Example
Using it with out-of-the-box definition, allowing all fields from the model.
Using it with custom definition of allowed fields
Other ideas not followed
I also considered to have a default value field in the config, but decided to go with field default definition on custom schema level
Another consideration was to create a class method factory in the OrderingSchema, so it can be define inline, but I wasn't sure if it would be used:
Notes
I didn't add field validation with Model definition, to keep the practices followed in the FilterSchema definition.
Also, I think is a good idea to keep this helpers class as simple as possible, and give room to personalization for more complex scenarios. However, let me know if validating
allowed_fields
with Model fields is something we would like to have, and I can update the PR.This was really useful in a personal project, were we needed to provide different ordering behaviors for a QuerySet and for an OpenSearch query. We had to do similar personalizations for pagination and filtering.